home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 May: Tool Chest / Dev.CD May 97 TC.toast / Sample Code / Snippets / Networking / ATP Demo 1.0 / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-28  |  31.9 KB  |  1,186 lines  |  [TEXT/MPS ]

  1. /*****************************************************************
  2.  
  3.     Program:    < ATP Demo >
  4.     File:        < Main.c >
  5.     
  6.     Written by  Scott Kuechle
  7.     of <Apple Macintosh Developer Technical Support>
  8.     
  9.     10/92 SRK created
  10.     8/94 SRK Modified to use a queue of parameter
  11.              blocks.
  12.  
  13.     Copyright © 1992, 1994 Apple Computer, Inc.
  14.     All rights reserved.
  15.     
  16. *****************************************************************/
  17.  
  18.  
  19. /*****************************************************************/
  20. /*  I N C L U D E S
  21. /*****************************************************************/
  22.  
  23. #include    "ATP Demo.h"
  24. #include    "ATP Demo.protos"
  25.  
  26. /********************************************************************
  27. /*  G L O B A L   V A R I A B L E   D E C L A R A T I O N S
  28. /********************************************************************/
  29.  
  30. DialogPtr myDialog;
  31. Boolean gHasWaitNextEvent,gInBackground,gGrowRect,gStopped,gStopRect,gGoRect,gHasSystem7;
  32. Boolean gATPEntityFilter;
  33. Boolean gReqClockTime,gSingleRequest,gStopRequests;
  34. MenuHandle ZoneMenu,ObjectMenu,TypeMenu;
  35. short LastZoneMenuChoice,LastTypeMenuChoice,LastObjectMenuChoice;
  36. SysEnvRec gMac;
  37. MenuHandle DataSizeMenu;
  38. Handle gTestDataHdl;
  39. long gTestDataSize;
  40.  
  41. /*****************************************************************/
  42. /*
  43. /* E X T E R N A L S
  44. /*
  45. /*****************************************************************/
  46.  
  47.  
  48. extern     Boolean SendReqToTarget();
  49. extern     void initializeATP();
  50. extern     void removeMyName();
  51. extern     void ATPLoop();
  52. extern     OSErr InitAppleTalk();
  53. extern     Boolean ATPZoneRequest (MenuHandle zoneMenu);
  54. extern     void LookupNames (MenuHandle lookupMenu,
  55.                     Boolean doObjects);
  56. extern     void GetZones();
  57. extern     void GetOurZone();
  58. extern     Str255 gZoneString,gTypeStr,gObjStr,gDataSizeStr;
  59. extern     short gMenuItem;
  60. extern    void removeATP();
  61. extern    void doGetRequest(ATPPBPtr atpPBPtr,
  62.                     char socket,
  63.                     short reqLength,
  64.                     Ptr reqPointer);
  65. extern    void DisplayStatusString(short whichString,Ptr displayStr);
  66. extern    QHdr gAvailQueue;
  67. extern    char gOurATPSocket;
  68.  
  69.  
  70.  
  71. #pragma segment Main
  72. // *****************************************************************
  73. // *    CopyPstr
  74. // *
  75. // *    copies a pascal string
  76. // *****************************************************************
  77. void CopyPstr(Ptr pSource, Ptr pDest)
  78. {
  79.     BlockMove(pSource, pDest, pSource[0]+1);
  80. }
  81.  
  82. // *****************************************************************
  83. // *    PStrCat
  84. // *
  85. // *    appends pascal string sourceStr, to pascal string destinationStr.
  86. // *    Overflow is checked, and the copy halts if the destination
  87. // *    string is filled.
  88. // *****************************************************************
  89. void PStrCat(Ptr sourceStr, Ptr destinationStr)
  90. {
  91.     unsigned int    srcIndex, dstIndex;
  92.     unsigned int    bytesToCopy;
  93.     
  94.     srcIndex = 1;
  95.     dstIndex = destinationStr[0] + 1;
  96.     bytesToCopy = sourceStr[0];
  97.     
  98.     while(bytesToCopy > 0 && dstIndex < 255)
  99.     {
  100.         destinationStr[dstIndex] = sourceStr[srcIndex];
  101.         dstIndex++;
  102.         srcIndex++;
  103.         bytesToCopy--;
  104.     }
  105.     destinationStr[0] = dstIndex - 1;
  106. }
  107. // *****************************************************************
  108. // *    DoActivate
  109. // *
  110. // * This is called when a window is activated or deactivated.
  111. // * In Sample, the Window Manager's handling of activate and
  112. // * deactivate events is sufficient. Other applications may have
  113. // * TextEdit records, controls, lists, etc., to activate/deactivate.
  114. // *****************************************************************
  115. void DoActivate (WindowPtr window, Boolean becomingActive)
  116. {
  117. #pragma unused (window,becomingActive)
  118.  
  119. } /*DoActivate*/
  120.  
  121.  
  122. // *****************************************************************
  123. // *    ShowError
  124. // *
  125. // * Our routine for displaying an error message in a dialog box.
  126. // *****************************************************************
  127. void ShowError(short index)
  128. {
  129. short itemHit;
  130.  
  131.     switch (index)
  132.     {
  133.         case atalkErr:
  134.             ParamText("\perror loading AppleTalk drivers!","\p","\p","\p");
  135.             break;
  136.         case memErr:
  137.             ParamText("\pmemory error.","\p","\p","\p");
  138.             break;
  139.         case menuErr:
  140.             ParamText("\perror initializing menus.","\p","\p","\p");
  141.             break;
  142.         case nbpErr:
  143.             ParamText("\pCouldn't register our name on the network (duplicate already exists).","\p","\p","\p");
  144.             break;
  145.         case noTargetErr:
  146.             ParamText("\ptarget not found.","\p","\p","\p");
  147.             break;
  148.         case badROMsErr:
  149.             ParamText("\pYour machine does not have at least 128K ROMs.","\p","\p","\p");
  150.             break;
  151.         case heapErr:
  152.             ParamText("\pNot enough heap space.","\p","\p","\p");
  153.             break;
  154.         case noMemErr:
  155.             ParamText("\pNot enough memory.","\p","\p","\p");
  156.             break;
  157.         case DrvrErr:
  158.             ParamText("\pFatal Device Manager error.","\p","\p","\p");
  159.             break;
  160.         case SktErr:
  161.             ParamText("\pError opening a socket.","\p","\p","\p");
  162.             break;
  163.         case RsrcErr:
  164.             ParamText("\pError getting program resources.","\p","\p","\p");
  165.             break;
  166.         case dataNotValidErr:
  167.             ParamText("\pTest data received was not valid.","\p","\p","\p");
  168.             break;
  169.         case dataIsValid:
  170.             ParamText("\pTest data received is correct!","\p","\p","\p");
  171.             break;
  172.  
  173.     }
  174.     
  175.     itemHit = Alert(rErrorDialog, nil);
  176.  
  177. }
  178.  
  179. // *****************************************************************
  180. // *    FatalError
  181. // *
  182. // * This is called when we detect that we cannot operate in the
  183. // * current environment.
  184. // *****************************************************************
  185. void FatalError(error)
  186.     short error;
  187. {
  188.  
  189.     ShowError(error);
  190.     ExitToShell();
  191. }
  192.  
  193. // *****************************************************************
  194. // *    IsAppWindow
  195. // *
  196. // *    Tells us whether or not a window is an application window
  197. // *
  198. // *****************************************************************
  199. Boolean IsAppWindow(window)
  200.     WindowPtr    window;
  201. {
  202.     short        windowKind;
  203.  
  204.     if ( window == nil )
  205.         return false;
  206.     else {    /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
  207.         windowKind = ((WindowPeek) window)->windowKind;
  208.         return (windowKind >= userKind) || (windowKind == dialogKind);
  209.     }
  210. } /* IsAppWindow */
  211.  
  212.  
  213.  
  214.  
  215. // *****************************************************************
  216. // *    IsDAWindow
  217. // *
  218. // *    Check if a window belongs to a desk accessory.
  219. // *****************************************************************
  220. Boolean IsDAWindow(WindowPtr window)
  221. {
  222.  
  223.     if (window == nil)
  224.         return false;
  225.     else    /* DA windows have negative windowKinds */
  226.         return((((WindowPeek)window)->windowKind < 0) ? true : false);
  227. } /*IsDAWindow*/
  228.  
  229. // *****************************************************************
  230. // *    DoCloseWindow
  231. // *
  232. // * Close a window. This handles only desk accessory windows because we do not
  233. // * allow our window to be closed. TESample provides an example of how to handle
  234. // * the closing of application windows.
  235. // *****************************************************************
  236. void DoCloseWindow (WindowPtr window)
  237. {
  238.     if (IsDAWindow(window))
  239.         CloseDeskAcc(((WindowPeek)window)->windowKind);
  240. } /*DoCloseWindow*/
  241.  
  242.  
  243.  
  244.  
  245. // *****************************************************************
  246. // *    outlinePopUpMenus
  247. // *
  248. // *     this is a group routine for drawing the popup menu outlines
  249. // *     compleat with drop shadow. the menu title is draw to the left
  250. // *    of the popUp item itself by this routine.
  251. // *****************************************************************
  252. void outlinePopUpMenus (WindowPtr whichWindow, Rect r, Str255 itemString)
  253. {
  254.     FrameRect(&r);
  255.     MoveTo(r.left + 2, r.bottom);
  256.     LineTo(r.right, r.bottom);
  257.     MoveTo(r.right, r.bottom);
  258.     LineTo(r.right, r.top + 2);
  259.     InsetRect(&r, 1, 1);
  260.     EraseRect(&r);
  261.     InsetRect(&r, -1, -1);
  262.     MoveTo(r.left + 5, r.top + 11);
  263.     TextFont(geneva);
  264.     TextSize(9);
  265.     DrawString(itemString);
  266.     drawPopUpTri(whichWindow, r);
  267. }
  268.  
  269.  
  270.  
  271. // *****************************************************************
  272. // *    UpdateUserItems
  273. // *
  274. // *     update procedure for the user items in our dialog.
  275. // *****************************************************************
  276. pascal void UpdateUserItems (WindowPtr whichWindow, short theItem)
  277. {
  278.     GrafPtr savedPort;
  279.     Rect r;
  280.     short kind;
  281.     Handle h;
  282.  
  283.  
  284.         GetPort(&savedPort);
  285.         SetPort(whichWindow);
  286.         GetDItem(whichWindow, theItem, &kind, &h, &r);
  287.         switch(theItem)
  288.         {
  289.             case kzoneItemID: 
  290.                 outlinePopUpMenus(whichWindow, r, gZoneString);
  291.                 break;
  292.                 
  293.             case ktypeItemID: 
  294.                 outlinePopUpMenus(whichWindow, r, gTypeStr);
  295.                 break;
  296.  
  297.             case kobjectItemID: 
  298.                 outlinePopUpMenus(whichWindow, r, gObjStr);
  299.                 break;
  300.  
  301.             case kPopupBorderID: 
  302.                 UpdateItemBorder(theItem, r);
  303.                 break;
  304.  
  305.             case kClockTimeBorder: 
  306.                 UpdateItemBorder(theItem, r);
  307.                 break;
  308.  
  309.             case kStatusText: 
  310.                 break;
  311.  
  312.         }
  313.         SetPort(savedPort);
  314. }
  315.  
  316. // *****************************************************************
  317. // *    DoModeless
  318. // *
  319. // * this handles mouse clicks inside our main dialog
  320. // *****************************************************************
  321. void DoModeless (DialogPtr whichDialog, short whichItem)
  322. {
  323.         Rect r;
  324.         short kind;
  325.         Handle h;
  326.         MenuHandle allPurposeMenu;
  327.         long chosen;
  328.         Point pt;
  329.         Str255 title;
  330.         Boolean reqSent;
  331.  
  332.  
  333.         if (whichDialog == myDialog)
  334.             {
  335.                 GetDItem(whichDialog, whichItem, &kind, &h, &r);
  336.                 switch(whichItem)
  337.                 {
  338.                     case kzoneItemID:
  339.                             pt.v = r.top;
  340.                             pt.h = r.left + 1;
  341.                             LocalToGlobal(&pt);
  342.                             SetCursor(*(GetCursor(watchCursor)));
  343.                             allPurposeMenu = NewMenu(ZoneMenuID, "");
  344.                             InsertMenu(allPurposeMenu, -1);
  345.                             GetZones(allPurposeMenu);
  346.  
  347.                             InitCursor();
  348.                             chosen = PopUpMenuSelect(allPurposeMenu, pt.v, pt.h, 1);
  349.                             if (chosen != 0)
  350.                             {
  351.                                 GetItem(allPurposeMenu, LoWord(chosen), gZoneString);
  352.                                 gMenuItem = LoWord(chosen);
  353.                                 CopyPstr("\p", gObjStr);
  354.                                 InvalRect(&r);                                        
  355.                             }
  356.                             InitCursor();
  357.                             DeleteMenu(ZoneMenuID);
  358.                             DisposeMenu(allPurposeMenu);
  359.                             
  360.                         break;
  361.                     case ktypeItemID:
  362.                             if (gATPEntityFilter == false)
  363.                             {
  364.                                 pt.v = r.top - 2;
  365.                                 pt.h = r.left + 1;
  366.                                 LocalToGlobal(&pt);
  367.                                 allPurposeMenu = NewMenu(TypeMenuID, "");
  368.                                 InsertMenu(allPurposeMenu, -1);
  369.                                 SetCursor(*(GetCursor(watchCursor)));
  370.                                 LookupNames(allPurposeMenu, false);
  371.                                 InitCursor();
  372.                                 chosen = PopUpMenuSelect(allPurposeMenu, pt.v, pt.h, 1);
  373.                                 if (chosen != 0)
  374.                                 {
  375.                                     GetItem(allPurposeMenu, LoWord(chosen), gTypeStr);
  376.                                     gMenuItem = LoWord(chosen);
  377.                                     InvalRect(&r);
  378.                                 }
  379.                                 
  380.                                 DeleteMenu(TypeMenuID);
  381.                                 DisposeMenu(allPurposeMenu);
  382.                             }
  383.                             else
  384.                                 SysBeep(1);
  385.                         break;
  386.                     case kobjectItemID:
  387.                             pt.v = r.top - 2;
  388.                             pt.h = r.left + 1;
  389.                             LocalToGlobal(&pt);
  390.                             allPurposeMenu = NewMenu(ObjectMenuID, "");
  391.                             InsertMenu(allPurposeMenu, -1);
  392.                             SetCursor(*(GetCursor(watchCursor)));
  393.                             LookupNames(allPurposeMenu, true);
  394.                             InitCursor();
  395.                             chosen = PopUpMenuSelect(allPurposeMenu, pt.v, pt.h, 1);
  396.                             if (chosen != 0)
  397.                             {
  398.                                 GetItem(allPurposeMenu, LoWord(chosen), gObjStr);
  399.                                 gMenuItem = LoWord(chosen);
  400.                                 InvalRect(&r);
  401.                             }
  402.  
  403.  
  404.                             DeleteMenu(ObjectMenuID);
  405.                             DisposeMenu(allPurposeMenu);
  406.                             
  407.                         break;
  408.  
  409.                     case kMoofFilterCheckBox: 
  410.                             if (gATPEntityFilter == false)
  411.                             {
  412.                                 SetCtlValue((ControlHandle)h,1);
  413.                                 gATPEntityFilter = true;
  414.                                 CopyPstr(atpEntityFilter, gTypeStr);
  415.                             }
  416.                             else
  417.                             {
  418.                                 SetCtlValue((ControlHandle)h,0);
  419.                                 gATPEntityFilter = false;
  420.                                 CopyPstr("\p", gTypeStr);
  421.                             }
  422.                             
  423.                             gObjStr[0] = 0;
  424.                                 /* update type popup menu */
  425.                             GetDItem(whichDialog, ktypeItemID, &kind, &h, &r);
  426.                             InvalRect(&myDialog->portRect);
  427.  
  428.                             
  429.                         break;    /* iMoofFilter */
  430.  
  431.                     case kReqDataButton:
  432.                             
  433.                                 /* clear status string first */
  434.                             ShowStatusString(kBlankText);
  435.                             
  436.                             GetControlTitle((ControlHandle)h,&title);
  437.                                 /* Is button titled "Send Requests" ? */
  438.                             if (IUCompPString(title,&kSendReqBtnText,nil) == 0)
  439.                             {
  440.                                     /* go ahead and send a request to the target */
  441.                                 reqSent = SendReqToTarget();
  442.                                 if (reqSent == true)
  443.                                 {
  444.                                         /* haven't stopped continuous requests */
  445.                                     gStopRequests = false;
  446.     
  447.                                         /* is the continuous requests option set? */
  448.                                     if (gSingleRequest == false)
  449.                                     {        /* reset button title to "Stop Requests" */
  450.                                         SetCTitle((ControlHandle)h, &kStopReqBtnText);
  451.                                     }
  452.                                 }
  453.                                 
  454.                             }
  455.                             else    /* reset button title to "Send Requests" */
  456.                             {
  457.                                 gStopRequests = true;
  458.                                 SetCTitle((ControlHandle)h, &kSendReqBtnText);
  459.                             }
  460.                             
  461.                         break;
  462.                         
  463.                 } /* of case */
  464.             }
  465.     }
  466.  
  467. // *****************************************************************
  468. // *    setEachUserItem
  469. // *
  470. // *    sets the update routine for our dialogs user items
  471. // *****************************************************************
  472. void setEachUserItem (short item)
  473. {
  474.     Rect r;
  475.     short kind;
  476.     Handle h;
  477.     
  478.         GetDItem(myDialog, item, &kind, &h, &r);
  479.         SetDItem(myDialog, item, userItem, (Handle)UpdateUserItems, &r);
  480.  
  481. }
  482.  
  483. // *****************************************************************
  484. // *    HiliteSendReqButton
  485. // *
  486. // *    set the state of the send request button
  487. // *****************************************************************
  488. void HiliteSendReqButton (short mode)
  489. {
  490.     Rect r;
  491.     short kind;
  492.     Handle h;
  493.  
  494.         GetDItem(myDialog, kReqDataButton, &kind, &h, &r);
  495.         HiliteControl((ControlHandle)h, mode);
  496. }
  497.  
  498. // *****************************************************************
  499. // *    DoMenuCommand
  500. // *
  501. // * This is called when an item is chosen from the menu bar (after calling
  502. // * MenuSelect or MenuKey). It performs the right operation for each command.
  503. // * It is good to have both the result of MenuSelect and MenuKey go to
  504. // * one routine like this to keep everything organized.
  505. // *****************************************************************
  506. void DoMenuCommand (long menuResult)
  507. {
  508.  
  509.     short menuID;        /*the resource ID of the selected menu*/
  510.     short menuItem;        /*the item number of the selected menu*/
  511.     short itemHit;
  512.     Str255 daName;
  513.     short daRefNum;
  514.     Boolean handledByDA;
  515.     MenuHandle menu;
  516.  
  517.  
  518.         menuID = HiWord(menuResult);    /* use built-ins (for efficiency)...*/
  519.         menuItem = LoWord(menuResult);    /*to get menu item number and menu number*/
  520.         switch (menuID)
  521.         {
  522.         case mApple: 
  523.                 switch(menuItem)
  524.                 {
  525.                     case iAbout:                /*bring up alert for About*/
  526.                         itemHit = Alert(rAboutDialog, nil);
  527.                         break;
  528.                     default:
  529.                             /*all non-About items in this menu are DAs*/
  530.                         GetItem(GetMHandle(mApple), menuItem, daName);
  531.                         daRefNum = OpenDeskAcc(daName);
  532.                     break;
  533.                 }
  534.             break;
  535.         case mFile: 
  536.                 switch(menuItem)
  537.                 {
  538.                     case iClose: 
  539.                         DoCloseWindow(FrontWindow());
  540.                         break;
  541.                     case iQuit: 
  542.                         Terminate();
  543.                         break;
  544.                 }
  545.             break;
  546.         case mEdit:        /*call SystemEdit for DA editing & MultiFinder*/
  547.                 {
  548.                     if (IsDAWindow(FrontWindow()))
  549.                         handledByDA = SystemEdit(menuItem - 1);
  550.                 }
  551.             break;
  552.         case mRequestOptions:
  553.                 {
  554.                     menu = GetMenuHandle(mRequestOptions);
  555.                     switch(menuItem)
  556.                     {
  557.                         case iReqClockTime:
  558.                                 gReqClockTime = true;
  559.                                 SetItemMark(menu, iReqClockTime, checkMark);
  560.                                 SetItemMark(menu, iReqData, noMark);
  561.                             break;
  562.                         case iReqData: 
  563.                                 gReqClockTime = false;
  564.                                 SetItemMark(menu, iReqClockTime, noMark);
  565.                                 SetItemMark(menu, iReqData, checkMark);
  566.                             break;
  567.                         case iSingleRequest:
  568.                                 gSingleRequest = true;
  569.                                 SetItemMark(menu, iSingleRequest, checkMark);
  570.                                 SetItemMark(menu, iMultipleRequests, noMark);
  571.                             break;
  572.                         case iMultipleRequests:
  573.                                 gSingleRequest = false;
  574.                                 SetItemMark(menu, iSingleRequest, noMark);
  575.                                 SetItemMark(menu, iMultipleRequests, checkMark);
  576.                             break;
  577.                     }
  578.                 }
  579.             break;
  580.  
  581.         }
  582.         
  583.         HiliteMenu(0);        /*unhighlight what MenuSelect (or MenuKey) hilited*/
  584.         
  585. } /*DoMenuCommand*/
  586.  
  587.  
  588. // *****************************************************************
  589. // *    AdjustMenus
  590. // *
  591. // * Enable and disable menus based on the current state.
  592. // * The user can only select enabled menu items. We set up all the menu items
  593. // * before calling MenuSelect or MenuKey, since these are the only times that
  594. // * a menu item can be selected. Note that MenuSelect is also the only time
  595. // * the user will see menu items. This approach to deciding what enable
  596. // * disable state a menu item has the advantage of concentrating all the decision-
  597. // * making in one routine, as opposed to being spread throughout the application.
  598. // * Other application designs may take a different approach that is just as valid.
  599. // *****************************************************************
  600. void AdjustMenus()
  601. {
  602.     WindowPtr window;
  603.     MenuHandle menu;
  604.  
  605.  
  606.         window = FrontWindow();
  607.  
  608.         menu = GetMHandle(mFile);
  609.         if (IsDAWindow(window))                /*we can allow desk accessories to be closed from the menu*/
  610.             EnableItem(menu, iClose);
  611.         else
  612.             DisableItem(menu, iClose);            /*but not our window*/
  613.  
  614.         menu = GetMHandle(mEdit);
  615.         if (IsDAWindow(window))
  616.         {                            /*a desk accessory might need the undo item */
  617.             EnableItem(menu, iUndo);
  618.             EnableItem(menu, iCut);
  619.             EnableItem(menu, iCopy);
  620.             EnableItem(menu, iPaste);
  621.             EnableItem(menu, iClear);
  622.         }
  623.         else
  624.         {                            /* but we do not support undo!!! */
  625.             DisableItem(menu, iUndo);
  626.             DisableItem(menu, iCut);
  627.             DisableItem(menu, iCopy);
  628.             DisableItem(menu, iPaste);
  629.             DisableItem(menu, iClear);
  630.         }
  631.  
  632. } /*AdjustMenus*/
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639. // *****************************************************************
  640. // *    Terminate
  641. // *
  642. // *    if we need to quit the program, we remove the connection
  643. // *    end (if any), deallocate any memory we used, remove our
  644. // *    nbp name from the network and exit.
  645. // *****************************************************************
  646. void Terminate()
  647. {
  648.     removeATP();
  649.     ExitToShell();
  650. }
  651.  
  652. // *****************************************************************
  653. // *    Exit
  654. // *
  655. // *    this routine is called for fatal control call errors. We exit
  656. // *    the program in this situation.
  657. // *****************************************************************
  658. void Exit(short message)
  659. {
  660.     ShowError(message);
  661.     Terminate();
  662. }
  663.  
  664. // *****************************************************************
  665. // *    DoIdleProc
  666. // *
  667. // *    this routine is called each time through our event loop. We
  668. // *    process any atpp errors that were returned and check for connections
  669. // *    coming and going.
  670. // *****************************************************************
  671. void DoIdleProc()
  672. {
  673.     ATPLoop();
  674. }
  675.  
  676.  
  677. // *****************************************************************
  678. // *    AdjustCursor
  679. // *
  680. // *Change the cursor's shape, depending on its position. This also calculates the region
  681. // * where the current cursor resides (for WaitNextEvent). If the mouse is ever outside of
  682. // * that region, an event would be generated, causing this routine to be called,
  683. // * allowing us to change the region to the region the mouse is currently in. If
  684. // * there is more to the event than just “the mouse moved”, we get called before the
  685. // * event is processed to make sure the cursor is the right one. In any (ahem) event,
  686. // * this is called again before we fall back into WNE.
  687. // *****************************************************************
  688. void AdjustCursor (Point mouse, RgnHandle region)
  689. {
  690.     WindowPtr window;
  691.     RgnHandle arrowRgn;
  692.     RgnHandle ourRgn;
  693.     Rect globalPortRect;
  694.  
  695.         window = FrontWindow();    /*we only adjust the cursor when we are in front*/
  696.         if ((!gInBackground) && (!IsDAWindow(window)))
  697.         {
  698.                 /*calculate regions for different cursor shapes*/
  699.             arrowRgn = NewRgn();
  700.             ourRgn = NewRgn();
  701.  
  702.                 /*start with a big, big rectangular region*/
  703.             SetRectRgn(arrowRgn, extremeNeg, extremeNeg, extremePos, extremePos);
  704.  
  705.                 /*calculate ourRgn*/
  706.             if (IsAppWindow(window))
  707.             {
  708.                 SetPort(window);            /*make a global version of the portRect*/
  709.                 SetOrigin(-window->portBits.bounds.left, -window->portBits.bounds.top);
  710.                 globalPortRect = window->portRect;
  711.                 RectRgn(ourRgn, &globalPortRect);
  712.                 SectRgn(ourRgn, window->visRgn, ourRgn);
  713.                 SetOrigin(0, 0);
  714.             }
  715.  
  716.                 /*subtract other regions from arrowRgn*/
  717.             DiffRgn(arrowRgn, ourRgn, arrowRgn);
  718.  
  719.                 /*change the cursor and the region parameter*/
  720.             if (PtInRgn(mouse, ourRgn))
  721.             {
  722.                 SetCursor(&qd.arrow);
  723.                 CopyRgn(arrowRgn, region);
  724.  
  725.             }
  726.  
  727.                 /*get rid of our local regions*/
  728.             DisposeRgn(arrowRgn);
  729.             DisposeRgn(ourRgn);
  730.         }
  731. } /*AdjustCursor*/
  732.  
  733. // *****************************************************************
  734. // *    UpdateItemBorder
  735. // *
  736. // *    re-draws the borders around our items
  737. // *****************************************************************
  738. void UpdateItemBorder (short item, Rect r)
  739. {
  740.     FontInfo fInfo;
  741.     Rect tRect;
  742.     Str255 theBorderString;
  743.  
  744.         switch(item)
  745.         {
  746.             case kPopupBorderID:
  747.                     strcpy(&theBorderString,"Select A Target Machine");
  748.                 break;
  749.  
  750.             case kClockTimeBorder:
  751.                     strcpy(&theBorderString,"Clock Time From Target Machine");
  752.                 break;
  753.  
  754.             default:
  755.                 break;
  756.         }
  757.  
  758.         c2pstr(theBorderString);
  759.  
  760.         GetFontInfo(&fInfo);
  761.         FrameRect(&r);
  762.         MoveTo(r.left + 5, r.top + fInfo.ascent / 2 - 1);
  763.         tRect.left = r.left + 4;
  764.         tRect.right = tRect.left + StringWidth(theBorderString) + 1;
  765.         tRect.top = r.top;
  766.         tRect.bottom = r.top + 1;
  767.         EraseRect(&tRect);
  768.         DrawString(&theBorderString);
  769.  
  770. }
  771.  
  772. // *****************************************************************
  773. // *    PlotSICN
  774. // *
  775. // * this is the PlotSICN code stolen from Tech Note #
  776. // *****************************************************************
  777. void PlotSICN (Rect theRect,SICNHand theSICN, short theIndex)
  778. {
  779.     SignedByte state;    /* we want a chance to restore original state */
  780.     BitMap srcBits;        /* built up around 'SICN' data so we can _CopyBits */
  781.  
  782.        /* check the index for a valid value */
  783.         if ((GetHandleSize((Handle)theSICN) / sizeof(SICN)) > theIndex)
  784.             {
  785.  
  786.     /* store the resource's current locked/unlocked condition */
  787.                 state = HGetState((Handle)theSICN);
  788.  
  789.     /* lock the resource so it won't move during the _CopyBits call */
  790.                 HLock((Handle)theSICN);
  791.  
  792.     /* set up the small icon's bitmap */
  793.            /*$PUSH*/
  794.            /*$R-*/
  795.     /* turn off range checking */
  796.                 srcBits.baseAddr = (Ptr)(&(**theSICN[theIndex]));
  797.            /*$POP*/
  798.                 srcBits.rowBytes = 2;
  799.                 SetRect(&srcBits.bounds, 0, 0, 16, 16);
  800.  
  801.     /* draw the small icon in the current grafport */
  802.                 CopyBits(&srcBits, &qd.thePort->portBits, &srcBits.bounds, &theRect, srcCopy, nil);
  803.  
  804.     /* restore the resource's locked/unlocked condition */
  805.                 HSetState((Handle)theSICN, state);
  806.             }
  807.  
  808. }
  809.  
  810. // *****************************************************************
  811. // *    drawPopUpTri
  812. // *
  813. // * this procedure draws the new "standard" SICN triangle now used
  814. // * in popup menus I guess the drop shadow was not enough of an
  815. // * indiciation to the users of the presence of the pop-up.
  816. // * standard in 7.0 and up systems 
  817. // *****************************************************************
  818. void drawPopUpTri (WindowPtr whichWindow, Rect r)
  819. {
  820.  
  821. #pragma unused (whichWindow)
  822.  
  823.     Handle popUpTri;
  824.     Rect popUpTriRect;
  825.  
  826.         popUpTri = GetResource('SICN', kStandardTriSICN);
  827.         if (popUpTri)
  828.         {
  829.             popUpTriRect = r;
  830.             popUpTriRect.right = popUpTriRect.right - 1;
  831.             popUpTriRect.left = popUpTriRect.right - 16;
  832.             popUpTriRect.top = popUpTriRect.top + 1;
  833.             popUpTriRect.bottom = popUpTriRect.top + 16;
  834.             PlotSICN(popUpTriRect, (SICNHand)popUpTri, 0);
  835.             ReleaseResource(popUpTri);
  836.         }
  837.  
  838.  
  839. }
  840.  
  841. // *****************************************************************
  842. // *    DoEvent
  843. // *
  844. // * Do the right thing for an event. Determine what kind of event it is, and call
  845. // * the appropriate routines.
  846. // *****************************************************************
  847. void DoEvent (EventRecord event)
  848. {
  849.  
  850.     short part;
  851.     char key;
  852.     WindowPtr whichWindow;
  853.  
  854.  
  855.     whichWindow = FrontWindow();
  856.  
  857.         switch(event.what)
  858.         {
  859.             case nullEvent: 
  860.                 break;
  861.             case mouseDown: 
  862.                     part = FindWindow(event.where, &whichWindow);
  863.                     if (part != 0)
  864.                     {
  865.                         switch(part)
  866.                         {
  867.                             case inMenuBar: 
  868.                                 /*process the menu command*/
  869.                                     AdjustMenus();
  870.                                     DoMenuCommand(MenuSelect(event.where));
  871.                                 break;
  872.                             case inSysWindow:                /*let the system handle the mouseDown*/
  873.                                 SystemClick(&event, whichWindow);
  874.                                 break;
  875.  
  876.                             case inContent: 
  877.                                 if (whichWindow != FrontWindow())
  878.                                     SelectWindow(whichWindow);
  879.                                 break;
  880.  
  881.                             case inDrag:                        /*pass screenBits.bounds to get all gDevices*/
  882.                                 DragWindow(whichWindow, event.where, &qd.screenBits.bounds);
  883.                                 break;
  884.                             
  885.                             case inGrow: 
  886.                                 break;
  887.                             case inZoomIn:
  888.                             case inZoomOut:
  889.                                 break;
  890.                         }
  891.                     }
  892.                 break;
  893.             case keyDown:
  894.             case autoKey:
  895.                                 /*check for menukey equivalents*/
  896.                     key = (char)(event.message & charCodeMask);
  897.                     if ((event.modifiers & cmdKey) != 0)    /*Command key down*/
  898.                     {
  899.                         if ((event.what == keyDown) || (event.what == autoKey))
  900.                         {
  901.                             AdjustMenus();            /*enable/disable/check menu items properly*/
  902.                             DoMenuCommand(MenuKey(key));
  903.                         }
  904.                     }
  905.                 break;                                /*call DoActivate with the window and...*/
  906.             case activateEvt:                        /*true for activate, false for deactivate*/
  907.                 DoActivate((WindowPtr)event.message, (event.modifiers & activeFlag) != 0);
  908.                 break;
  909.             case updateEvt: 
  910.                 break;
  911.             case osEvent: 
  912.                 switch(event.message >> 24)    /*high byte of message*/
  913.                 {
  914.                     case suspendResumeMessage:
  915.                             gInBackground = (event.message & resumeMask) == 0;
  916.                             DoActivate(FrontWindow(), !gInBackground);
  917.                     break;
  918.                 }
  919.  
  920.         }
  921.     } /*DoEvent*/
  922.  
  923.  
  924. // *****************************************************************
  925. // *    EventLoop
  926. // *
  927. // * Get events forever, and handle them by calling DoEvent.
  928. // * Get the events by calling WaitNextEvent, if it's available, otherwise
  929. // * by calling GetNextEvent. Also call AdjustCursor each time through the loop.
  930. // *****************************************************************
  931. void EventLoop()
  932. {
  933.  
  934.     RgnHandle cursorRgn;
  935.     Boolean gotEvent;
  936.     EventRecord event;
  937.     long sleepTime;
  938.     WindowPtr whichDialog;
  939.     short whichItem;
  940.     
  941.     
  942.         cursorRgn = NewRgn();            /*we’ll pass WNE an empty region the 1st time thru*/
  943.         sleepTime = 15;
  944.         do
  945.         {
  946.             if (gHasWaitNextEvent)    /*put us 'asleep' forever under MultiFinder*/
  947.             {
  948.                 gotEvent = WaitNextEvent(everyEvent, &event, sleepTime, cursorRgn);
  949.             }
  950.             else
  951.             {
  952.                 SystemTask();                /*must be called if using GetNextEvent*/
  953.                 gotEvent = GetNextEvent(everyEvent, &event);
  954.             }
  955.             DoIdleProc();
  956.             AdjustCursor(event.where, cursorRgn); /*make sure we have the right cursor*/
  957.             whichDialog = FrontWindow();
  958.                 /* don't pass command keys or <enter> keys to our dialog */
  959.             if(!((event.what==keyDown)&&(event.modifiers & cmdKey)) && (IsDialogEvent(&event)))        
  960.             {
  961.                 if (DialogSelect(&event, &whichDialog, &whichItem))
  962.                     DoModeless(whichDialog, whichItem);
  963.             }
  964.             else        
  965.                 DoEvent(event);
  966.         }
  967.         while (true);                    /*loop forever; we quit through an ExitToShell*/
  968. }
  969.  
  970. // *****************************************************************
  971. // *    Main
  972. // *
  973. // *****************************************************************
  974. main()
  975. {
  976.     MaxApplZone();            /*expand the heap so code segments load at the top*/
  977.     CheckEnvirons();        /*check for some basic requirements; exits if not met*/
  978.  
  979.     InitGraf(&qd.thePort);
  980.     InitFonts();
  981.     InitWindows();
  982.     InitMenus();
  983.     TEInit();
  984.     InitDialogs(nil);
  985.     InitCursor();
  986.     
  987.     if (InitAppleTalk() != noErr)
  988.     {
  989.         ShowError(atalkErr);
  990.         ExitToShell();
  991.     }
  992.     else
  993.     {
  994.         Initialize();            /*initialize the program*/
  995.         UnloadSeg(&Initialize);    /*note that Initialize must not be in Main!*/
  996.         EventLoop();            /*call the main event loop*/
  997.     }
  998. }
  999.  
  1000.  
  1001. #pragma segment Initialize
  1002.  
  1003. // *****************************************************************
  1004. // *    TrapAvailable
  1005. // *
  1006. // * Check to see if a given trap is implemented. This is only used by the
  1007. // * Initialize routine in this program, so we put it in the Initialize segment.
  1008. // * The recommended approach to see if a trap is implemented is to see if
  1009. // * the address of the trap routine is the same as the address of the
  1010. // * Unimplemented trap.
  1011. // *****************************************************************
  1012. Boolean TrapAvailable(tNumber,tType)
  1013.     short        tNumber;
  1014.     TrapType    tType;
  1015. {
  1016.     if ( ( tType == ToolTrap ) &&
  1017.         ( gMac.machineType > envMachUnknown ) &&
  1018.         ( gMac.machineType < envMacII ) )
  1019.     {        /* it's a 512KE, Plus, or SE */
  1020.         tNumber = tNumber & 0x03FF;
  1021.         if ( tNumber > 0x01FF )                    /* which means the tool traps */
  1022.             tNumber = _Unimplemented;            /* only go to 0x01FF */
  1023.     }
  1024.     return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
  1025. } /*TrapAvailable*/
  1026.  
  1027. // *****************************************************************
  1028. // *    SetupUserItems
  1029. // *
  1030. // *****************************************************************
  1031. void SetupUserItems()
  1032. {
  1033.     setEachUserItem(kzoneItemID);
  1034.     setEachUserItem(ktypeItemID);
  1035.     setEachUserItem(kobjectItemID);
  1036.     setEachUserItem(kPopupBorderID);
  1037.     setEachUserItem(kClockTimeBorder);
  1038.  
  1039. }
  1040.  
  1041.  
  1042.  
  1043. // *****************************************************************
  1044. // *    Initialize
  1045. // *
  1046. // *    program initialization
  1047. // *****************************************************************
  1048. void Initialize()
  1049. {
  1050.  
  1051.     Rect r;
  1052.     short kind;
  1053.     Handle h;
  1054.     Handle menuBar;
  1055.     DialogPeek dp;
  1056.     ATPPBPtr atpPBPtr;
  1057.     myATPParamBlockPtr myATPPBPtr;
  1058.     MenuHandle menu;
  1059.  
  1060.         gInBackground = false;
  1061.             
  1062.         gZoneString[0] = 0;gTypeStr[0] = 0;gObjStr[0] = 0;
  1063.  
  1064.         GetOurZone();
  1065.  
  1066.             /*    we will allocate our own window storage instead of letting the Window */
  1067.             /*    Manager do it because GetNewWindow may load in temp. resources before */
  1068.             /*    making the NewPtr call, and this can lead to heap fragmentation. */
  1069.         myDialog = (DialogPtr)(NewPtr(sizeof(DialogRecord)));
  1070.         if (myDialog == nil)
  1071.             Exit(memErr);
  1072.  
  1073.  
  1074.         myDialog = GetNewDialog(rDialog, (Ptr)myDialog, (DialogPtr)-1);
  1075.  
  1076.         SetPort(myDialog);
  1077.  
  1078.         dp = (DialogPeek)myDialog;
  1079.  
  1080.         TextFont(geneva);
  1081.         TextSize(9);
  1082.  
  1083.         SetWTitle(myDialog, "\pATP");
  1084.  
  1085.         ShowWindow(myDialog);
  1086.  
  1087.         LastZoneMenuChoice = 0;
  1088.         LastTypeMenuChoice = 0;
  1089.         LastObjectMenuChoice = 0;        
  1090.         
  1091.         SetupUserItems();
  1092.  
  1093.             /* turn on type entity filter (check box) initially */
  1094.         GetDItem(myDialog, kMoofFilterCheckBox, &kind, &h, &r);
  1095.         SetCtlValue((ControlHandle)h,1);
  1096.         gATPEntityFilter = true;
  1097.         CopyPstr(atpEntityFilter, gTypeStr);
  1098.         gObjStr[0] = 0;
  1099.         
  1100.         menuBar = GetNewMBar(rMenuBar);        /*read menus into menu bar*/
  1101.         if (menuBar == nil)
  1102.             Exit(menuErr);
  1103.         SetMenuBar(menuBar);                    /*install menus*/
  1104.         DisposHandle(menuBar);
  1105.         AddResMenu(GetMHandle(mApple), 'DRVR');    /*add DA names to Apple menu*/
  1106.         DrawMenuBar();
  1107.  
  1108.             /* initialize our "Request Options" menu */
  1109.         menu = GetMenuHandle(mRequestOptions);
  1110.  
  1111.         gReqClockTime = true;
  1112.         SetItemMark(menu, iReqClockTime, checkMark);
  1113.         gSingleRequest = false;
  1114.         SetItemMark(menu, iMultipleRequests, checkMark);
  1115.  
  1116.         gStopRequests = false;
  1117.         initializeATP();
  1118.  
  1119.         gTestDataHdl = GetResource(kTestDataType,kTestDataRsrcID);
  1120.         if (gTestDataHdl == NULL)
  1121.             Exit(RsrcErr);
  1122.  
  1123.         gTestDataSize = MaxSizeRsrc(gTestDataHdl);
  1124.  
  1125.         atpPBPtr = GetQElement(&gAvailQueue);
  1126.         if (atpPBPtr != NULL)
  1127.         {
  1128.             myATPPBPtr = GetOurPBPtr(atpPBPtr);
  1129.                 /* issue a get request so that we may receive requests from
  1130.                     other machines */
  1131.             doGetRequest(atpPBPtr,
  1132.                         gOurATPSocket,
  1133.                         sizeof(struct ourReqData),
  1134.                         myATPPBPtr->reqData);
  1135.         }
  1136.         else
  1137. /* ???????????????????????? */;
  1138.  
  1139. } /*Initialize*/
  1140.  
  1141. // *****************************************************************
  1142. // *    CheckEnvirons
  1143. // *
  1144. // *    check the current operating environment
  1145. // *****************************************************************
  1146. void CheckEnvirons()
  1147. {
  1148.     long  total, contig, response;
  1149.     OSErr ignoreError;
  1150.  
  1151.     
  1152.         /* ignore the error returned from SysEnvirons; even if an error occurred,*/
  1153.         /* the SysEnvirons glue will fill in the SysEnvRec*/
  1154.             ignoreError = SysEnvirons(sysEnvironsVersion, &gMac);
  1155.  
  1156.         /* Make sure that the machine has at least 128K ROMs. If it doesn't, exit. */
  1157.         if (gMac.machineType < 0) FatalError(9);
  1158.         if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap) FatalError(10);
  1159.         PurgeSpace(&total, &contig);
  1160.         if (total < kMinSpace)
  1161.             if (UnloadScrap() != noErr)
  1162.                 FatalError(11);
  1163.             else
  1164.             {
  1165.                 PurgeSpace(&total, &contig);
  1166.                 if (total < kMinSpace)
  1167.                     FatalError(11);
  1168.             }
  1169.             
  1170.         /* verify if WaitNextEvent, Gestalt and PPCToolbox are available */
  1171.         gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
  1172.         if (TrapAvailable(_Gestalt, ToolTrap)) 
  1173.         {         /* verify if system 7.0 */
  1174.             Gestalt(gestaltSystemVersion,&response );
  1175.             if (response >= 0x0700)
  1176.                 gHasSystem7 = true;
  1177.             else gHasSystem7 = false;
  1178.         }
  1179.         else
  1180.         {
  1181.             SysBeep(20);
  1182.             gHasSystem7 = false;
  1183.         }
  1184.  
  1185. }
  1186.